package org.sems.sems.ConfigController;


import org.apache.http.client.config.RequestConfig;
import org.apache.http.util.EntityUtils;
import org.sems.sems.Mapper.SemsConfigMapper;
import org.sems.sems.entity.JyspkMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.regex.Pattern;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


@Controller
public class VideoBroadcastController {

    private final SimpMessagingTemplate messagingTemplate;
    private static final Pattern INVALID_FILENAME_CHARS = Pattern.compile("[\\\\/:*?？<>\\r\\n|]");
    private static String cookid;
    @Autowired
    private SemsConfigMapper semsConfigMapper;

    public VideoBroadcastController(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    // 用于 REST 测试触发广播：POST /video/broadcast
    @MessageMapping("/broadcast")
    public void broadcastVideo(JyspkMessage videoData) {
        System.out.println(videoData);
        messagingTemplate.convertAndSend("/topic/videos", videoData);
        // 读取参数
        VideoBroadcastController.cookid=semsConfigMapper.SelectConfigById(12).getValue();
        try (CloseableHttpClient client = HttpClients.createDefault()) {
            downloadPage(client, "", videoData.gjc(), videoData.yhm(), videoData.yhsfdm(), messagingTemplate, 2);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    private static void downloadPage(CloseableHttpClient client, String pcursor, String keyword, String YHM, int YHSFDM, SimpMessagingTemplate messagingTemplate, int pageNum) throws Exception {
        if (pageNum == 0) {
            System.out.println("结束下载-------------------------------------");
            return;
        }

        // 构造 GraphQL 请求体
        JsonObject body = new JsonObject();
        body.addProperty("operationName", "visionSearchPhoto");
        body.addProperty("query", GRAPHQL_QUERY);
        JsonObject variables = new JsonObject();
        variables.addProperty("keyword", keyword);
        if (pcursor != null && !pcursor.isEmpty()) {
            variables.addProperty("pcursor", pcursor);
        } else {
            variables.add("pcursor", null);
        }
        variables.addProperty("page", "search");
        body.add("variables", variables);

        // —— 超时配置 ——
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(5_000)           // 建立连接最多等待 5 秒
                .setConnectionRequestTimeout(5_000) // 从连接池获取连接最多等待 5 秒
                .setSocketTimeout(10_000)           // 等待服务器返回数据最多 10 秒
                .build();

        // 构造 POST 请求
        HttpPost post = new HttpPost("https://www.kuaishou.com/graphql");
        post.setConfig(config);  // 绑定超时配置
        post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
        post.setHeader("Cookie", VideoBroadcastController.cookid);
        post.setHeader("Referer", "https://www.kuaishou.com/search/video?searchKey=" + keyword);
        post.setHeader("Content-Type", "application/json");
        post.setEntity(new StringEntity(body.toString(), "UTF-8"));

        System.out.println("已经到这3");
        // 执行请求，并在超时或网络错误时捕获 IOException
        try (CloseableHttpResponse resp = client.execute(post)) {
            System.out.println("已经到这5");
           /* String respBody = new String(resp.getEntity().getContent().readAllBytes(), "UTF-8");
            JsonObject root = JsonParser.parseString(respBody).getAsJsonObject();*/

            // 更推荐的方式：自动消费实体、自动关闭 InputStream
            String respBody = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8);
            JsonObject root = JsonParser.parseString(respBody).getAsJsonObject();

            // 处理 errors
            if (root.has("errors")) {
                System.err.println("GraphQL Errors: " + root.get("errors"));
                return;
            }

            // 取 data.visionSearchPhoto
            JsonObject data = root.has("data") && !root.get("data").isJsonNull()
                    ? root.getAsJsonObject("data")
                    : null;
            if (data == null) {
                System.err.println("响应中缺少 data 节点，跳过本页。");
                return;
            }
            JsonObject vision = data.has("visionSearchPhoto") && !data.get("visionSearchPhoto").isJsonNull()
                    ? data.getAsJsonObject("visionSearchPhoto")
                    : null;
            if (vision == null) {
                System.err.println("响应中缺少 visionSearchPhoto，跳过本页。");
                return;
            }

            // 取 feeds 数组
            JsonElement feedsElem = vision.get("feeds");
            if (feedsElem == null || !feedsElem.isJsonArray()) {
                System.err.println("feeds 不是数组或为 null，跳过本页。");
                return;
            }
            JsonArray feeds = feedsElem.getAsJsonArray();

            // 遍历并打印视频标题
            for (JsonElement elem : feeds) {
                JsonObject photo = elem.getAsJsonObject()
                        .getAsJsonObject("photo");
                if (photo == null) continue;

                String caption = photo.has("caption") && !photo.get("caption").isJsonNull()
                        ? photo.get("caption").getAsString()
                        : "unknown";
                String CoverUrl = photo.has("coverUrl") && !photo.get("coverUrl").isJsonNull()
                        ? photo.get("coverUrl").getAsString()
                        : "unknown";
                String safeName = INVALID_FILENAME_CHARS.matcher(caption).replaceAll("");
                System.out.println("视频标题：" + safeName);


                // videoUrl 处理
                JsonElement urlElem = photo.get("photoUrl");
                if (urlElem == null || urlElem.isJsonNull()) {
                    System.err.println("缺少 photoUrl，跳过：" + safeName);
                    continue;
                }
                String videoUrl = urlElem.getAsString();

                // 这里可以调用 downloadFile(client, videoUrl, path) 去下载
                JyspkMessage jyspkMessage = new JyspkMessage(keyword, videoUrl,CoverUrl, new Date(), YHM, YHSFDM, safeName, "无");

                messagingTemplate.convertAndSend("/topic/videos", jyspkMessage);

                System.out.println(safeName + ".mp4 -- 加载成功！");
            }

            // 处理下一页 pcursor
            JsonElement cursorElem = vision.get("pcursor");
            String nextCursor = (cursorElem != null && !cursorElem.isJsonNull())
                    ? cursorElem.getAsString()
                    : null;

            if (nextCursor == null || nextCursor.isEmpty()) {
                System.out.println("视频下载完毕！");
            } else {
                System.out.println("本页完成，pcursor=" + pcursor + "，下页 pcursor=" + nextCursor);
                Thread.sleep(4000);
                downloadPage(client, nextCursor, keyword, YHM, YHSFDM, messagingTemplate, pageNum -1);
            }
        } catch (IOException ioe) {
            System.err.println("请求超时或网络错误：" + ioe.getMessage());
        }
    }


  /*  private static void downloadPage(CloseableHttpClient client, String pcursor, String keyword,String YHM,int YHSFDM,SimpMessagingTemplate messagingTemplate) throws Exception {
        // 构造 GraphQL 请求体
        JsonObject body = new JsonObject();
        body.addProperty("operationName", "visionSearchPhoto");
        body.addProperty("query", GRAPHQL_QUERY);
        JsonObject variables = new JsonObject();
        variables.addProperty("keyword", keyword);
        if (pcursor != null && !pcursor.isEmpty()) {
            variables.addProperty("pcursor", pcursor);
        } else {
            variables.add("pcursor", null);
        }
        variables.addProperty("page", "search");
        body.add("variables", variables);

        HttpPost post = new HttpPost("https://www.kuaishou.com/graphql");
        post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
        post.setHeader("Cookie", "kpf=PC_WEB; clientid=3; did=web_524f19cfede45c54b2e24b345e5baf71; userId=592760441; didv=1746629672000; kuaishou.server.webday7_st=ChprdWFpc2hvdS5zZXJ2ZXIud2ViZGF5Ny5zdBKwAU5hWtmq7RhvBu22NDQzTm-NOzAbdX_0i5tC94UJaHol1Ms0nz2VjiaEZ3HT_8NJ7uslxyAqrHOhl6gUGhzuk1_uTHTCU4piUHlcGX6oMaG9cT8qczdib7XeAE23vBbW33h_3uxUcGjAZjVj-Fy8aTHFWkrrKdNIMkYS_84oNkOqwoKPzeoPg4bil0t5liBqobkwOKx4SBQcIMhDDxkNk3A6SMsvF_HuXaC_UVcyYq2mGhIO-p_LPhJRcsBCrrX5eWI4YxEiIB7NPcQ9GbahqEXs2RrWt3IH5LWn3JCs2YGkazwvpiM7KAUwAQ; kuaishou.server.webday7_ph=6b28d7d2d05e08920bae9e7bc575e962ce09; kpn=KUAISHOU_VISION");
        post.setHeader("Referer", "https://www.kuaishou.com/search/video?searchKey=" + keyword);
        post.setHeader("Content-Type", "application/json");
        post.setEntity(new StringEntity(body.toString(), "UTF-8"));

        try (CloseableHttpResponse resp = client.execute(post)) {
            String respBody = new String(resp.getEntity().getContent().readAllBytes(), "UTF-8");
            JsonObject root = JsonParser.parseString(respBody).getAsJsonObject();

            // 如果有 errors 字段，打印后直接返回
            if (root.has("errors")) {
                System.err.println("GraphQL Errors: " + root.get("errors").toString());
                return;
            }

            // data 节点
            JsonObject data = root.has("data") && !root.get("data").isJsonNull()
                    ? root.getAsJsonObject("data")
                    : null;
            if (data == null) {
                System.err.println("响应中缺少 data 节点，跳过本页。");
                return;
            }

            // visionSearchPhoto 节点
            JsonObject vision = data.has("visionSearchPhoto") && !data.get("visionSearchPhoto").isJsonNull()
                    ? data.getAsJsonObject("visionSearchPhoto")
                    : null;
            if (vision == null) {
                System.err.println("响应中缺少 visionSearchPhoto，跳过本页。");
                return;
            }

            // feeds 数组
            JsonElement feedsElem = vision.get("feeds");
            if (feedsElem == null || !feedsElem.isJsonArray()) {
                System.err.println("feeds 不是数组或为 null，跳过本页。");
                return;
            }
            JsonArray feeds = feedsElem.getAsJsonArray();

            // 遍历下载
            for (JsonElement elem : feeds) {
                JsonObject photo = elem.getAsJsonObject()
                        .getAsJsonObject("photo");
                if (photo == null) continue;

                // caption 处理
                JsonElement captionElem = photo.get("caption");
                String caption = (captionElem != null && !captionElem.isJsonNull())
                        ? captionElem.getAsString()
                        : "unknown";
                String safeName = INVALID_FILENAME_CHARS.matcher(caption).replaceAll("");

                // videoUrl 处理
                JsonElement urlElem = photo.get("photoUrl");
                if (urlElem == null || urlElem.isJsonNull()) {
                    System.err.println("缺少 photoUrl，跳过：" + safeName);
                    continue;
                }
                String videoUrl = urlElem.getAsString();

                JyspkMessage jyspkMessage = new JyspkMessage(keyword, videoUrl, new Date(), YHM,YHSFDM ,safeName, "无");

                messagingTemplate.convertAndSend("/topic/videos", jyspkMessage);

                System.out.println(safeName + ".mp4 -- 加载成功！");
            }

            // 下一页 pcursor
            JsonElement cursorElem = vision.get("pcursor");
            String nextCursor = (cursorElem != null && !cursorElem.isJsonNull())
                    ? cursorElem.getAsString()
                    : null;

            if (nextCursor == null || nextCursor.isEmpty()) {
                System.out.println("视频下载完毕！");
            } else {
                System.out.println("本页完成，pcursor=" + pcursor + "，下页 pcursor=" + nextCursor);
                Thread.sleep(1000);
                downloadPage(client, nextCursor, keyword,YHM,YHSFDM,messagingTemplate);
            }
        }
    }*/

    // 可选：客户端 WebSocket 主动发消息触发广播（如前端通过 /app/sendVideo 发送）
    @MessageMapping("/sendVideo")
    public void handleIncoming(JyspkMessage videoData) {
        System.out.println(videoData);
        messagingTemplate.convertAndSend("/topic/videos", videoData);
    }
    private static void downloadFile(CloseableHttpClient client, String url, String path) throws IOException {
        HttpGet get = new HttpGet(url);
        try (CloseableHttpResponse resp = client.execute(get);
             InputStream in = resp.getEntity().getContent();
             FileOutputStream out = new FileOutputStream(path)) {
            byte[] buf = new byte[8192];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
        }
    }
    private static final String GRAPHQL_QUERY = """
            fragment photoContent on PhotoEntity {
              __typename
              id
              duration
              caption
              originCaption
              likeCount
              viewCount
              commentCount
              realLikeCount
              coverUrl
              photoUrl
              photoH265Url
              manifest
              manifestH265
              videoResource
              coverUrls {
                url
                __typename
              }
              timestamp
              expTag
              animatedCoverUrl
              distance
              videoRatio
              liked
              stereoType
              profileUserTopPhoto
              musicBlocked
            }
            
            fragment recoPhotoFragment on recoPhotoEntity {
              __typename
              id
              duration
              caption
              originCaption
              likeCount
              viewCount
              commentCount
              realLikeCount
              coverUrl
              photoUrl
              photoH265Url
              manifest
              manifestH265
              videoResource
              coverUrls {
                url
                __typename
              }
              timestamp
              expTag
              animatedCoverUrl
              distance
              videoRatio
              liked
              stereoType
              profileUserTopPhoto
              musicBlocked
            }
            
            fragment feedContent on Feed {
              type
              author {
                id
                name
                headerUrl
                following
                headerUrls {
                  url
                  __typename
                }
                __typename
              }
              photo {
                ...photoContent
                ...recoPhotoFragment
                __typename
              }
              canAddComment
              llsid
              status
              currentPcursor
              tags {
                type
                name
                __typename
              }
              __typename
            }
            
            query visionSearchPhoto($keyword: String, $pcursor: String, $searchSessionId: String, $page: String, $webPageArea: String) {
              visionSearchPhoto(keyword: $keyword, pcursor: $pcursor, searchSessionId: $searchSessionId, page: $page, webPageArea: $webPageArea) {
                result
                llsid
                webPageArea
                feeds {
                  ...feedContent
                  __typename
                }
                searchSessionId
                pcursor
                aladdinBanner {
                  imgUrl
                  link
                  __typename
                }
                __typename
              }
            }
            """;

}
